package com.spring.cloud.eurekaclientzuul;

import com.spring.cloud.eurekaclientzuul.route.MyRouteLocator;
import io.github.resilience4j.ratelimiter.RateLimiterConfig;
import io.github.resilience4j.ratelimiter.RateLimiterRegistry;
import java.time.Duration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.discovery.ServiceRouteMapper;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableZuulProxy
@EnableCircuitBreaker
public class EurekaClientZuulApplication {

    public static void main(String[] args) {

        SpringApplication.run(EurekaClientZuulApplication.class, args);
    }

    private RateLimiterRegistry rateLimiterRegistry;
    private RateLimiterConfig rateLimiterConfig;

    //此处限流配置建议使用代码配置 有时候yml配置不生效
    @Bean(name = "rateLimiterConfig")
    public RateLimiterConfig initRateLimiterConfig(){

        if(rateLimiterConfig == null){
            rateLimiterConfig = RateLimiterConfig.custom()
                    .limitRefreshPeriod(Duration.ofMillis(5000))
                    .limitForPeriod(3)
                    .timeoutDuration(Duration.ofMillis(10))
                    .build();

        }

        return rateLimiterConfig;
    }

    @Bean(name = "rateLimiterRegistry")
    public RateLimiterRegistry initRateLimiterRegistry(){

        if(rateLimiterConfig==null){
            initRateLimiterConfig();
        }
        if(rateLimiterRegistry == null){
            rateLimiterRegistry = RateLimiterRegistry.of(rateLimiterConfig);
            rateLimiterRegistry.rateLimiter("user");
        }
        return rateLimiterRegistry;

    }

    //Zuul配置
    @Autowired
    protected ZuulProperties zuulProperties;

    //服务器配置
    @Autowired
    protected ServerProperties server;

    // 服务注册表
    @Qualifier("eurekaRegistration")
    @Autowired(required = false)
    private Registration registration;


    //服务发现客户端
    @Autowired
    private DiscoveryClient discovery;

    //服务路由映射器
    @Autowired
    private ServiceRouteMapper serviceRouteMapper;

    @Bean(name = "routeLocator")
    public MyRouteLocator initMyRouteLocator(){

        return new MyRouteLocator(this.server.getServlet().getContextPath(),
                this.discovery,
                this.zuulProperties,
                this.serviceRouteMapper,
                this.registration);
    }

}
